﻿var imageController = {
    //image array
    imgArr: null,
    ids: 0,
    imgWidth: 0,
    imgHeight: 0,
    curId: 0,
    //canvas
    stage: null,
    layer: null,
    imgObj: null,
    curImgLabel: null,
    //tools
    curToolID: 0,//no tool is actived
    list: $("#listImage"),
    drag: $("#drag"),
    zoomin: $("#in"),
    zoomout: $("#out"),
    ruler: $("#ruler"),
    rotate_clockwise: $("#rotate_clockwise"),
    rotate_counterclockwise: $("#rotate_counterclockwise"),
    ruler: $("#ruler"),
    previous: $("#previous"),
    play: $("#play"),
    next: $("#next"),
    info: $("#info"),
    //variables
    zoomtime: 0,
    scale: 1,
    playstate: false,
    playing: null,
    line: null,
    label: null,
    moving: false,
    x1: 0,
    y1: 0,
    x2: 0,
    y2: 0,
    group: null,
    pX: 0,
    pY: 0,
    //functions
    constructor: function () {
        this.stage = new Kinetic.Stage({
            container: "container",
            width: window.innerWidth,
            height: window.innerHeight
        });
        this.layer = new Kinetic.Layer({
        });
        this.group = new Kinetic.Group({
            x: 0,
            y: 0
        });
        this.imgObj = new Kinetic.Image({
            x: 0,
            y: 0
        });
        this.curImgLabel = new Kinetic.Text({
            fontSize: 16,
            fontFamily: 'Calibri',
            fill: '#f0ad4e'
        });
        //this.line = new Kinetic.Line({
        //    points: [0, 0, 0, 0],
        //    stroke: "red"
        //});
        this.group.add(this.imgObj);
        //this.group.add(this.line);
        this.layer.add(this.group);
        this.layer.add(this.curImgLabel);
        this.stage.add(this.layer);
    },
    activeTool: function (toolID, state) {
        var p = this;
        switch (toolID) {
            case 0:
                break;
            case 1://drag
                p.group.setDraggable(state);
                if (state == true) {
                    p.drag.attr("src", home + "Images/drag_active.png");
                }
                else {
                    p.drag.attr("src", home + "Images/drag.png");
                }
                break;
            case 2:
                if (state == true) {
                    p.zoomin.attr("src", home + "Images/zoom_in_active.png");
                }
                else {
                    p.zoomin.attr("src", home + "Images/zoom_in.png");
                }
                break;
            case 3:
                if (state == true) {
                    p.zoomout.attr("src", home + "Images/zoom_out_active.png");
                }
                else {
                    p.zoomout.attr("src", home + "Images/zoom_out.png");
                }
                break;
            case 4:
                if (state == true) {
                    p.ruler.attr("src", home + "Images/ruler_active.png");
                }
                else {
                    p.ruler.attr("src", home + "Images/ruler.png");
                }
                break;
        }
    },
    changeToolState: function (toolID) {
        var p = this;
        p.activeTool(p.curToolID, false);
        if (p.curToolID == toolID) {
            p.curToolID = 0;
        }
        else {
            p.curToolID = toolID;
            p.activeTool(p.curToolID, true);
        }
    },
    enableEventsHandling: function (tools) {
        var p = imageController;
        for (var t in tools) {
            switch (tools[t].name) {
                case "drag":
                    if (tools[t].state == true) {
                        p.drag.on("click", function () {
                            p.changeToolState(1);
                        });
                    }
                    else {
                        p.drag.off('click');
                    }
                    break;
                case "imgObj":
                    if (tools[t].state == true) {
                        p.imgObj.on('mouseover', function () {
                            //document.body.style.cursor = 'pointer';
                            switch(p.curToolID){
                                case 1://drag
                                    $("body").css({ "cursor": 'move' });
                                    break;
                                case 2://zoom in
                                    $("body").css({ "cursor": 'url(' + home + 'Images/zoom_in_cursor.png), zoom-in' });
                                    break;
                                case 3://zoom out
                                    $("body").css({ "cursor": 'url(' + home + 'Images/zoom_out_cursor.png), zoom-out' });
                                    break;
                                case 4://ruler
                                    $("body").css({ "cursor": 'crosshair' });
                                    break;
                            }
                            
                        });
                        p.imgObj.on('mouseout', function () {
                            document.body.style.cursor = 'default';
                        });
                        //this.imgObj.on("dragstart", function (e) {
                        //p.info.text("Drag start: " + e.offsetX);
                        //});
                        //this.imgObj.on("dragmove", function (e) {
                        //    p.info.text("Drag move: " + e.offsetX);
                        //});
                        //this.imgObj.on("dragend", function (e) {
                        //    p.info.text("Drag end: " + e.offsetX);
                        //});
                        p.imgObj.on("mousedown touchstart", function (event) {
                            switch (p.curToolID) {
                                case 0://no actived tool
                                    break;
                                case 1://drag
                                    break;
                                case 2://zoomin
                                    p.zoomtime++;
                                    p.zoom();
                                    break;
                                case 3:
                                    if (p.zoomtime > 0) {
                                        p.zoomtime--;
                                        p.zoom();
                                    }
                                    break;
                                case 4://ruler
                                    //if (p.moving) {
                                    //    p.moving = false;
                                    //    p.layer.draw();
                                    //}
                                    //else {
                                        var mousePos = p.stage.getMousePosition();
                                        //p.info.text(p.group.getX() + " " + p.group.getY() + " " + mousePos.x + " " + mousePos.y);
                                        p.x1 = (mousePos.x * p.scale - (p.group.getX() - p.pX));
                                        p.y1 = (mousePos.y * p.scale - (p.group.getY() - p.pY));
                                        p.line = new Kinetic.Line({
                                            points: [p.x1, p.y1, p.x1, p.y1],
                                            stroke: "red"
                                        });
                                        p.group.add(p.line);
                                        p.moving = true;
                                        //p.layer.draw();
                                    //}
                                    break;
                            }
                        });
                        p.imgObj.on("mousemove", function (event) {
                            switch (p.curToolID) {
                                case 4://ruler
                                    if (p.moving) {
                                        var mousePos = p.stage.getMousePosition();
                                        p.line.getPoints()[1].x = (mousePos.x * p.scale - (p.group.getX() - p.pX));
                                        p.line.getPoints()[1].y = (mousePos.y * p.scale - (p.group.getY() - p.pY));
                                        p.layer.drawScene();//p.layer.draw() ???
                                    }
                                    break;
                            }
                        });
                        //p.imgObj.on("dblclick", function (event) {
                        //    event.stopPropagation();
                        //});
                        p.stage.on("mouseup", function (event) {
                            switch (p.curToolID) {
                                case 4://ruler
                                    var mousePos = p.stage.getMousePosition();
                                    p.moving = false;
                                    p.x2 = (mousePos.x * p.scale - (p.group.getX() - p.pX));
                                    p.y2 = (mousePos.y * p.scale - (p.group.getY() - p.pY));
                                    p.line.getPoints()[1].x = p.x2;
                                    p.line.getPoints()[1].y = p.y2;
                                    var midX = (p.line.getPoints()[0].x + p.line.getPoints()[1].x) / 2;
                                    var midY = (p.line.getPoints()[0].y + p.line.getPoints()[1].y) / 2;
                                    p.label = new Kinetic.Text({
                                        x: midX,
                                        y: midY,
                                        text: p.calculateDistance(p.x1, p.y1, p.x2, p.y2),
                                        fontSize: 20,
                                        fontFamily: 'Calibri',
                                        fill: 'green'
                                    });
                                    p.group.add(p.label);
                                    p.layer.drawScene();
                                    break;
                            }
                        });
                    }
                    else {
                        p.imgObj.off('mouseover mouseout mousedown touchstart mousemove touchmove');
                        p.stage.off('mouseup');
                    }
                    break;
                case "list":
                    if (tools[t].state == true) {
                        p.list.on("click", "img", function (event) {
                            var t = $(this);
                            p.curId = t.attr("id");
                            p.drawImage(p.imgArr[p.curId]);
                            //$("#ImageID").prop({
                            //    "value": p.curId
                            //});//not update viewmodel
                            indicationUpdateVM.ImageID(p.curId);
                        });
                    }
                    else {
                        p.list.off('click');
                    }
                    break;
                case "zoomin":
                    if (tools[t].state == true) {
                        p.zoomin.on("click", function () {
                            p.changeToolState(2);
                        });
                    }
                    else {
                        p.zoomin.off('click');
                    }
                    break;
                case "zoomout":
                    if (tools[t].state == true) {
                        p.zoomout.on("click", function () {
                            p.changeToolState(3);
                        });
                    }
                    else {
                        p.zoomout.off('click');
                    }
                    break;
                case "ruler":
                    if (tools[t].state == true) {
                        p.ruler.on("click", function () {
                            p.changeToolState(4);
                        });
                    }
                    else {
                        p.ruler.off('click');
                    }
                    break;
                case "rotate_clockwise":
                    if (tools[t].state == true) {
                        p.rotate_clockwise.on("click", function () {
                            p.group.rotateDeg(90);
                            p.layer.draw();
                        });
                        p.rotate_clockwise.on("mousedown", function () {
                            p.rotate_clockwise.attr("src", home + "Images/rotate_clockwise_clicked.png");
                        });
                        p.rotate_clockwise.on("mouseup", function () {
                            p.rotate_clockwise.attr("src", home + "Images/rotate_clockwise.png");
                        });
                    }
                    else {
                        p.rotate_clockwise.off('click mousedown mouseup');
                    }
                    break;
                case "rotate_counterclockwise":
                    if (tools[t].state == true) {
                        p.rotate_counterclockwise.on("click", function () {
                            p.group.rotateDeg(-90);
                            p.layer.draw();
                        });
                        p.rotate_counterclockwise.on("mousedown", function () {
                            p.rotate_counterclockwise.attr("src", home + "Images/rotate_counterclockwise_clicked.png");
                        });
                        p.rotate_counterclockwise.on("mouseup", function () {
                            p.rotate_counterclockwise.attr("src", home + "Images/rotate_counterclockwise.png");
                        });
                    }
                    else {
                        p.rotate_counterclockwise.off('click mousedown mouseup');
                    }
                    break;
                case "previous":
                    if (tools[t].state == true) {
                        p.previous.on("click", function () {
                            if (p.curId > 0) {
                                p.curId--;
                                p.drawImage(p.imgArr[p.curId]);
                                indicationUpdateVM.ImageID(p.curId);
                            }
                        });
                        p.previous.on("mousedown", function () {
                            if (p.curId > 0) {
                                p.previous.attr("src", home + "Images/previous_clicked.png");
                            }
                        });
                        p.previous.on("mouseup", function () {
                            p.previous.attr("src", home + "Images/previous.png");
                        });
                    }
                    else {
                        p.previous.off('click mousedown mouseup');
                    }
                    break;
                case "play":
                    if (tools[t].state == true) {
                        p.play.on("click", function () {
                            p.playstate = !p.playstate;
                            if (p.playstate == true) {
                                p.playing = setInterval(p.playMovie, 33);
                                p.play.attr("src", home + "Images/pause.png");
                                var tools = [
                                    { name: "previous", state: false },
                                    { name: "next", state: false }
                                ];
                                p.enableEventsHandling(tools);
                            }
                            else {
                                clearInterval(p.playing);
                                p.play.attr("src", home + "Images/play.png");
                                indicationUpdateVM.ImageID(p.curId);
                                var tools = [
                                    { name: "previous", state: true },
                                    { name: "next", state: true }
                                ];
                                p.enableEventsHandling(tools);
                            }
                        });
                    }
                    else {
                        p.play.off('click');
                    }
                    break;
                case "next":
                    if (tools[t].state == true) {
                        p.next.on("click", function () {
                            if (p.curId < p.ids - 1) {
                                p.curId++;
                                p.drawImage(p.imgArr[p.curId]);
                                indicationUpdateVM.ImageID(p.curId);
                            }
                        });
                        p.next.on("mousedown", function () {
                            if (p.curId < p.ids - 1) {
                                p.next.attr("src", home + "Images/next_clicked.png");
                            }
                        });
                        p.next.on("mouseup", function () {
                            p.next.attr("src", home + "Images/next.png");
                        });
                    }
                    else {
                        p.next.off('click mousedown mouseup');
                    }
                    break;
            };
        };
    },
    clearOldData: function () {
        var self = this;
        //play
        self.stopMovie();
        //list
        self.list.empty();
        //zoom
        self.zoomtime = 0;
        self.scale = 1;

        if (self.stage != null) {
            self.stage.destroy();
        }   
        self.constructor();

        //disable all tools
        var tools = [
            { name: "drag", state: false },
            { name: "imgObj", state: false },
            { name: "list", state: false },
            { name: "zoomin", state: false },
            { name: "zoomout", state: false },
            { name: "ruler", state: false },
            { name: "rotate_clockwise", state: false },
            { name: "rotate_counterclockwise", state: false },
            { name: "previous", state: false },
            { name: "play", state: false },
            { name: "next", state: false }
        ];
        self.enableEventsHandling(tools);
        self.changeToolState(0);
        //imgArr
        if (self.imgArr == null) {
            self.imgArr = [];
        }
        else {
            self.imgArr.splice(0, self.ids);//remove all array item
        }
        self.ids = 0;
        self.imgWidth = 0;
        self.imgHeight = 0;
        self.curId = 0;
    },
    loadImages: function (patientID, imageVisitID, imageID) {
        var self = this;
        //lay thong tin anh
        messageController.processing("get_meta");
        var getMetaData = $.ajax({
            type: 'post',
            url: home + 'Radiologist/GetImageMeta',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: JSON.stringify({ PatientID: patientID, ImageVisitID: imageVisitID }),
            success: function (data) {
                //alert(JSON.stringify(data));
                self.ids = data.IDs;
                self.imgWidth = data.ImageWidth;
                self.imgHeight = data.ImageHeight;
                if (self.ids > 0) {
                    self.imgObj.setWidth(self.imgWidth);
                    self.imgObj.setHeight(self.imgHeight);
                    self.group.setOffset({ x: self.imgWidth / 2, y: self.imgHeight / 2 });
                    self.group.setPosition({ x: self.imgWidth / 2, y: self.imgHeight / 2 });
                    self.curImgLabel.setPosition({ x: 0, y: 0 });
                    self.pX = self.imgWidth / 2;
                    self.pY = self.imgHeight / 2;
                    //self.layer.setOffset({ x: self.imgWidth / 2, y: self.imgHeight / 2 });
                    //self.layer.setPosition({ x: self.imgWidth / 2, y: self.imgHeight / 2 });
                    //self.info.text(self.imgWidth + " " + self.layer.getPosition().x + " " + self.layer.getOffset().x);
                    var newImage;
                    //luu anh vao mang
                    for (var id = 0; id < self.ids; id++) {
                        newImage = new Image();
                        newImage.src = home + 'Radiologist/GetImage?patientID=' + patientID + '&imageVisitID=' + imageVisitID + '&index=' + id;
                        self.imgArr.push(newImage);
                    }

                    //dua danh sach anh vao DOM
                    var newDiv = $("<div />");
                    for (var id = 0; id < self.ids; id++) {
                        //$("<img />").replaceWith(imgArr[id]).attr({
                        $(self.imgArr[id]).attr({
                            "id": id,
                        }).appendTo(newDiv);
                    }
                    newDiv.appendTo(self.list);

                    //ve anh len Canvas
                    self.imgArr[imageID].onload = function () {
                        self.drawImage(this);
                    };

                    //active tools
                    var tools = [
                        { name: "drag", state: true },
                        { name: "imgObj", state: true },
                        { name: "list", state: true },
                        { name: "zoomin", state: true },
                        { name: "zoomout", state: true },
                        { name: "ruler", state: true },
                        { name: "rotate_clockwise", state: true },
                        { name: "rotate_counterclockwise", state: true },
                    ];
                    if (self.ids > 1) {
                        tools.push(
                            { name: "previous", state: true },
                            { name: "play", state: true },
                            { name: "next", state: true }
                        );
                    }
                    self.enableEventsHandling(tools);
                    //complete
                    messageController.processComplete("image_loading");
                }
                else {
                    messageController.processComplete("no_image");
                }
            },
            error: function (err) {
                if (err.status == 200) {
                    messageController.processComplete(err.responseText);
                }
                else {
                    messageController.processComplete("process_error");
                }
            }
        });
    },
    drawImage: function (imageSource) {
        this.imgObj.setImage(imageSource);
        var curId = Number(this.curId) + 1;
        this.curImgLabel.setText("Image: " + curId + "/" + this.ids);
        this.layer.draw();
        //this.info.append(" " + this.curId);
    },
    zoom: function () {
        this.scale = Math.pow(1.25, this.zoomtime);
        this.group.setScale({ x: this.scale, y: this.scale });
        this.layer.draw();
    },
    playMovie: function () {
        //this.curId++;
        //if ((this.curId & this.ids) == 16) {
        //    this.curId = 0;
        //}
        //this.draw(this.imgArr[this.curId]);

        var p = imageController;
        p.curId++;
        p.curId = p.curId % p.ids;
        //if ((p.curId % p.ids) == 0) {
        //    p.curId = 0;
        //}
        p.drawImage(p.imgArr[p.curId]);
    },
    stopMovie: function (){
        if (this.playstate == true) {
            this.play.trigger("click");
        }
    },
    calculateDistance: function (x1, y1, x2, y2) {
        var distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
        distance *= 0.264583333;
        distance = Math.round(distance * 100 / 1) / 100;
        return distance + "mm";

    }
};
//imageController.constructor();